﻿
Imports std

Namespace job
    Namespace simple
        Public Enum command As Byte
            increment = 0
            decrement

            last
        End Enum

        Public Module _simple
            Public Function valid(ByVal i As command) As Boolean
                Return i >= firstOfSimple AndAlso i < command.last
            End Function
        End Module
    End Namespace

    Namespace storage
        Public Enum command As Byte
            write = simple.command.last
            uniqueWrite
            delete
            modify
            read
            seek
            capacity
            valuesize
            list
            status
            open
            close
            full
            health
            retire
            empty
            sizeof
            keycount
            sync
            version
            lockwrite
            unlockwrite
            lockread
            unlockread
            lock
            unlock

            last
        End Enum

        Public Module _storage
            Public Const count As Int64 = command.last - job.firstOfStorage

            Public Function valid(ByVal i As command) As Boolean
                Return i >= firstOfStorage AndAlso i < command.last
            End Function

            Public Function valid(ByVal i As storageJob) As Boolean
                Return Not i Is Nothing AndAlso
                       i.valid()
            End Function

            Public Function valid(ByVal i As ijob) As Boolean
                Return valid(convertor.cast(Of storageJob)(i, False))
            End Function

            Private ReadOnly hashable_commands() As command = {command.write,
                                                               command.uniqueWrite,
                                                               command.delete,
                                                               command.modify,
                                                               command.read,
                                                               command.seek,
                                                               command.sizeof}

            Public Function hashable(ByVal i As command) As Boolean
                Return hashable_commands.has(i)
            End Function

            Private ReadOnly not_hashable_keyrequired_commands() As command = {command.sync}

            Public Function not_hashable_keyrequired(ByVal i As command) As Boolean
                Return not_hashable_keyrequired_commands.has(i)
            End Function

            Public Function keyrequired(ByVal i As command) As Boolean
                Return hashable(i) OrElse not_hashable_keyrequired(i)
            End Function

            Private ReadOnly buffrequired_commands() As command = {command.write,
                                                                   command.uniqueWrite,
                                                                   command.modify}

            Public Function buffrequired(ByVal i As command) As Boolean
                Return buffrequired_commands.has(i)
            End Function

            Private ReadOnly i64required_commands() As command = {command.write,
                                                                  command.uniqueWrite,
                                                                  command.modify,
                                                                  command.sync}

            Public Function i64required(ByVal i As command) As Boolean
                Return i64required_commands.has(i)
            End Function

            Private ReadOnly resultrespond_commands() As command = {command.capacity,
                                                                    command.close,
                                                                    command.delete,
                                                                    command.empty,
                                                                    command.full,
                                                                    command.health,
                                                                    command.keycount,
                                                                    command.list,
                                                                    command.lock,
                                                                    command.lockread,
                                                                    command.lockwrite,
                                                                    command.modify,
                                                                    command.open,
                                                                    command.read,
                                                                    command.retire,
                                                                    command.seek,
                                                                    command.sizeof,
                                                                    command.status,
                                                                    command.sync,
                                                                    command.uniqueWrite,
                                                                    command.unlock,
                                                                    command.unlockread,
                                                                    command.unlockwrite,
                                                                    command.valuesize,
                                                                    command.write}

            Public Function resultrespond(ByVal i As command) As Boolean
                Return resultrespond_commands.has(i)
            End Function

            Private ReadOnly keyrespond_commands() As command = {command.version}

            Public Function keyrespond(ByVal i As command) As Boolean
                Return keyrespond_commands.has(i)
            End Function

            Private ReadOnly buffrespond_commands() As command = {command.read}

            Public Function buffrespond(ByVal i As command) As Boolean
                Return buffrespond_commands.has(i)
            End Function

            Private ReadOnly vsrespond_commands() As command = {command.list}

            Public Function vsrespond(ByVal i As command) As Boolean
                Return vsrespond_commands.has(i)
            End Function

            Private ReadOnly i64respond_commands() As command = {command.read,
                                                                 command.capacity,
                                                                 command.valuesize,
                                                                 command.status,
                                                                 command.sizeof,
                                                                 command.keycount}

            Public Function i64respond(ByVal i As command) As Boolean
                Return i64respond_commands.has(i)
            End Function

            Private ReadOnly i64_2respond_commands() As command = {command.status}

            Public Function i64_2respond(ByVal i As command) As Boolean
                Return i64_2respond_commands.has(i)
            End Function

            Private ReadOnly i64_timestamp_commands() As command = {command.write,
                                                                    command.uniqueWrite,
                                                                    command.modify}

            Public Function i64_timestamp(ByVal i As command) As Boolean
                Return i64_timestamp_commands.has(i)
            End Function

            Public Sub traversal(ByVal d As void(Of String, command, Int64),
                                 Optional ByVal count As void(Of Int64) = Nothing)
                assert(Not d Is Nothing)
                assert(enum_traversal(Of command)(Sub(ByRef i As command, ByRef s As String)
                                                      If i <> command.last Then
                                                          d(s, i, i - firstOfStorage)
                                                      End If
                                                  End Sub,
                                                  count))
            End Sub

            Public Delegate Sub traversal_delegate(ByVal name As String, ByVal cmd As command, ByVal index As Int64)
            Public Sub traversal(ByVal d As traversal_delegate)
                assert(Not d Is Nothing)
                traversal(Sub(ByRef x, ByRef y, ByRef z) d(x, y, z))
            End Sub
        End Module
    End Namespace

    Namespace operation
        Public Enum command As Byte
            run = storage.command.last
            status
            result
            update

            last
        End Enum

        Public Module _operation
            Public Function valid(ByVal i As command) As Boolean
                Return i >= firstOfOperation AndAlso i < command.last
            End Function

            Private ReadOnly id_required_commands() As command = {command.run,
                                                                  command.status,
                                                                  command.result,
                                                                  command.update}

            Public Function id_required(ByVal i As command) As Boolean
                Return id_required_commands.has(i)
            End Function

            Private ReadOnly action_required_commands() As command = {command.run}

            Public Function action_required(ByVal i As command) As Boolean
                Return action_required_commands.has(i)
            End Function

            Private ReadOnly result_required_commands() As command = {}

            Public Function result_required(ByVal i As command) As Boolean
                Return result_required_commands.has(i)
            End Function

            Private ReadOnly percentage_required_commands() As command = {command.update}

            Public Function percentage_required(ByVal i As command) As Boolean
                Return percentage_required_commands.has(i)
            End Function

            Private ReadOnly id_respond_commands() As command = {command.run}

            Public Function id_respond(ByVal i As command) As Boolean
                Return id_required_commands.has(i)
            End Function

            Private ReadOnly action_respond_commands() As command = {}

            Public Function action_respond(ByVal i As command) As Boolean
                Return action_respond_commands.has(i)
            End Function

            Private ReadOnly result_respond_commands() As command = {command.run,
                                                                     command.status,
                                                                     command.result,
                                                                     command.update}

            Public Function result_respond(ByVal i As command) As Boolean
                Return result_respond_commands.has(i)
            End Function

            Private ReadOnly percentage_respond_commands() As command = {command.status}

            Public Function percentage_respond(ByVal i As command) As Boolean
                Return percentage_respond_commands.has(i)
            End Function
        End Module
    End Namespace

    Namespace ufs
        Public Enum command As Byte
            open = operation.command.last
            create
            close
            append
            read
            delete

            last
        End Enum
    End Namespace

    Public Enum command As Byte
        invalid = maxUInt8
    End Enum

    Public Module _job
        Public Const firstOfSimple As simple.command = simple.command.increment
        Public Const firstOfStorage As storage.command = storage.command.write
        Public Const firstOfOperation As operation.command = operation.command.run
        Public Const firstOfUfs As ufs.command = ufs.command.open

        Sub New()
            assert(firstOfSimple = 0)
            assert(firstOfStorage = simple.command.last)
            assert(firstOfOperation = storage.command.last)
            assert(firstOfUfs = operation.command.last)
        End Sub
    End Module
End Namespace

Public Module _distributor
    Public Const targetQueuesSeparator As Char = character.comma
End Module
